{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "36be991d-4fb7-47f3-8b7c-f043dde5f8e2",
   "metadata": {},
   "outputs": [],
   "source": [
    "import cv2\n",
    "import glob\n",
    "import numpy as np\n",
    "#遍历原图目录下的文件\n",
    "import shutil\n",
    "import keyboard\n",
    "import os\n",
    "\n",
    "def Draw(img_src, contours_list):\n",
    "    #初始化最大圆面积\n",
    "    maxa = cv2.contourArea(contours_list[0])\n",
    "    #初始化最小圆面积\n",
    "    mina = cv2.contourArea(contours_list[0])\n",
    "    #初始化半径\n",
    "    maxp = minp = 0\n",
    "    #遍历查找最大最小圆\n",
    "    for i in range(len(contours_list)):\n",
    "        # cv2.drawContours(img_src, [contours_list[i]], -1, (0, 255, 0), 1)\n",
    "        area = cv2.contourArea(contours_list[i])\n",
    "        if area > maxa:\n",
    "            maxp = i\n",
    "            maxa = area\n",
    "        if area < mina:\n",
    "            minp = i\n",
    "            mina = area\n",
    "    cv2.drawContours(img_src, [contours_list[maxp]], -1, (0, 0, 255), 1)#绘制外圆 \n",
    "    (x, y), radius = cv2.minEnclosingCircle(contours_list[maxp])#查找外圆圆心\n",
    "    cv2.putText(img_src, str(int(maxa)*16), (int(x-15), int(y-radius-2)), cv2.FONT_HERSHEY_COMPLEX, 0.3, (0, 0, 255), 1)#打印外圆面积\n",
    "    cv2.drawContours(img_src, [contours_list[minp]], -1, (255, 0, 0), 1)#绘制内圆\n",
    "    (x, y), radius = cv2.minEnclosingCircle(contours_list[maxp])#查找内圆圆心 \n",
    "    cv2.putText(img_src, str(int(mina)*16), (int(x-15), int(y)), cv2.FONT_HERSHEY_COMPLEX, 0.3, (255, 0, 0), 1)#打印内圆面积\n",
    "\n",
    "    \n",
    "    \n",
    "#图像处理提取圆\n",
    "def imgsignal(imgCUT,xz,y1,y2):\n",
    "    #限制对比度自适应直方图均衡化\n",
    "    clahe = cv2.createCLAHE(xz,(y1,y1))\n",
    "    dst = clahe.apply(imgCUT)\n",
    "    #高斯双边模糊\n",
    "    dst = cv2.bilateralFilter(dst, 0, 10, 5)\n",
    "    #图像锐化\n",
    "    kernel = np.array([[0, -1, 0], [-1, 5, -1], [0, -1, 0]], np.float32) #定义一个核\n",
    "    dst = cv2.filter2D(dst, -1, kernel=kernel)\n",
    "    #canny边缘提取\n",
    "    blur = cv2.GaussianBlur(dst, (3, 3), 0)  # 用高斯滤波处理原图像降噪\n",
    "    imgCanny = cv2.Canny(blur, 60, 110)  # 50是最小阈值,150是最大阈值\n",
    "\n",
    "    #轮廓提取\n",
    "    contours = []\n",
    "    contours, _ = cv2.findContours(imgCanny, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)#求出边界点阵\n",
    "    contours_List=[]\n",
    "    for i in range(len(contours)):\n",
    "        hull = cv2.convexHull(contours[i])#查找凸包\n",
    "        length = cv2.arcLength(contours[i],False)#计算边界长度\n",
    "        area = cv2.contourArea(hull)#计算包围面积\n",
    "        # print(\"轮廓%d的面积:%d\" % (i, area))\n",
    "        if area > 1E4 and length > 1e2:\n",
    "            # cv2.drawContours(resized,[hull],-1,(0,0,255),1)\n",
    "            contours_List.append(hull)\n",
    "    return contours_List\n",
    "\n",
    "#轮廓分组\n",
    "def imgdevision(contours_List,sign):\n",
    "    preprearea = 0\n",
    "    prearea = 0\n",
    "    area = 0\n",
    "    contoursl = []\n",
    "    contoursm = []\n",
    "    contoursr = [] \n",
    "    for i in range(len(contours_List)): #对得到的连通轮廓进行分组\n",
    "    # area = cv2.contourArea(contours[i])\n",
    "  \n",
    "        (x, y), radius = cv2.minEnclosingCircle(contours_List[i])#提取外接圆\n",
    "        area_c = 3.14 * radius * radius#计算外接圆面积\n",
    "        preprearea = prearea\n",
    "        prearea = area\n",
    "        area = cv2.contourArea(contours_List[i])\n",
    "        #检测边界与圆的面积误差，并且简单进行跳变检测\n",
    "        if area_c / area < 1.1 and abs(area-prearea)>200 and abs(area-preprearea)>300:\n",
    "            \n",
    "            if 0 < x < 200 and (sign==1 or sign==0):\n",
    "                contoursl.append(contours_List[i])\n",
    "            elif 300 < x < 500 and (sign==2 or sign==0):\n",
    "                contoursm.append(contours_List[i])        \n",
    "            elif 500 < x < 760 and (sign==3 or sign==0):\n",
    "                contoursr.append(contours_List[i])\n",
    "                \n",
    "    return contoursl,contoursm,contoursr\n",
    "\n",
    "f = glob.glob(r'yuanturesult/*.jpg')\n",
    "for fnum in f:\n",
    "    img=cv2.imread(fnum,1)\n",
    "    #尺寸提取\n",
    "    img_height = img.shape[0]\n",
    "    img_width = img.shape[1]\n",
    "    #裁剪\n",
    "    width = 768\n",
    "    height = 512\n",
    "    dim = (width, height)\n",
    "    resized = cv2.resize(img, dim)#更改图像大小\n",
    "    imgGRAY=cv2.cvtColor(resized, cv2.COLOR_BGR2GRAY)#灰度化\n",
    "    imgCUT = imgGRAY[0:height-50,0:width]  #裁剪图像\n",
    "    contours_List=[]\n",
    "    #边缘提取\n",
    "    fre = 17\n",
    "    nux=2\n",
    "    nuy=2\n",
    "    \n",
    "\n",
    "\n",
    "    contours_List=imgsignal(imgCUT,fre,nux,nuy)\n",
    "    #分割 \n",
    "    contoursl,contoursm,contoursr = imgdevision(contours_List,0)\n",
    "\n",
    "    i = 0\n",
    "    j = 0\n",
    "    k = 0\n",
    "    while(len(contoursl) < 3):  \n",
    "        while(nux+j<7):\n",
    "            j=j+1\n",
    "            contours_List=imgsignal(imgCUT,fre,nux+j,nuy)\n",
    "            contoursl,_,_ = imgdevision(contours_List,1)\n",
    "            if(len(contoursl) >= 2):\n",
    "                break\n",
    "            while(nux+k<7):\n",
    "                k=k+1\n",
    "                contours_List=imgsignal(imgCUT,fre,nux,nuy+k)\n",
    "                contoursl,_,_ = imgdevision(contours_List,1)\n",
    "                if(len(contoursl) >= 2):\n",
    "                    break\n",
    "                while(fre-i>9):\n",
    "                    i=i+1\n",
    "                    contours_List=imgsignal(imgCUT,fre-i,nux+j,nuy+k)\n",
    "                    contoursl,_,_ = imgdevision(contours_List,1)\n",
    "                    if(len(contoursl) >= 2):\n",
    "                        break\n",
    "                    \n",
    "        else:\n",
    "            # print(\"error!\")\n",
    "            break\n",
    "\n",
    "    i = 0\n",
    "    j = 0\n",
    "    k = 0\n",
    "    \n",
    "    #遍历阈值\n",
    "    while(len(contoursm) < 3):\n",
    "        while(nux+j<7):\n",
    "            j=j+1\n",
    "            contours_List=imgsignal(imgCUT,fre,nux+j,nuy)\n",
    "            _,contoursm,_ = imgdevision(contours_List,2)\n",
    "            if(len(contoursm) >= 2):\n",
    "                break\n",
    "            while(nux+k<7):\n",
    "                k=k+1\n",
    "                contours_List=imgsignal(imgCUT,fre,nux,nuy+k)\n",
    "                _,contoursm,_ = imgdevision(contours_List,2)\n",
    "                if(len(contoursm) >= 2):\n",
    "                    break\n",
    "                while(fre-i>9):\n",
    "                    i=i+1\n",
    "                    contours_List=imgsignal(imgCUT,fre-i,nux+j,nuy+k)\n",
    "                    _,contoursm,_ = imgdevision(contours_List,2)\n",
    "                    if(len(contoursm) >= 2):\n",
    "                        break\n",
    "        else:\n",
    "            # print(\"error!\")\n",
    "            break\n",
    "  \n",
    "    i = 0\n",
    "    j = 0\n",
    "    k = 0\n",
    "    while(len(contoursr) < 3):\n",
    "\n",
    "        while(nux+j<7):\n",
    "            j=j+1\n",
    "            contours_List=imgsignal(imgCUT,fre,nux+j,nuy)\n",
    "            _,_,contoursr = imgdevision(contours_List,3)\n",
    "            if(len(contoursr) >= 2):\n",
    "                break\n",
    "            while(nux+k<7):\n",
    "                k=k+1\n",
    "                contours_List=imgsignal(imgCUT,fre,nux,nuy+k)\n",
    "                _,_,contoursr = imgdevision(contours_List,3)\n",
    "                if(len(contoursr) >= 2):\n",
    "                    break\n",
    "                while(fre-i>9):\n",
    "                    i=i+1\n",
    "                    contours_List=imgsignal(imgCUT,fre-i,nux+j,nuy+k)\n",
    "                    _,_,contoursr = imgdevision(contours_List,3)\n",
    "                    if(len(contoursr) >= 2):\n",
    "                        break\n",
    "        else:\n",
    "            # print(\"error!\")\n",
    "            break\n",
    "      \n",
    "    # print('contoursl',len(contoursl))\n",
    "    # print('contoursm',len(contoursm))\n",
    "    # print('contoursr',len(contoursr))\n",
    "\n",
    "\n",
    "    \n",
    "    if(len(contoursl)>=2 and len(contoursm)>=2 and len(contoursr)>=2):\n",
    "        Draw(resized, contoursl)\n",
    "        Draw(resized, contoursm)\n",
    "        Draw(resized, contoursr)\n",
    "        path1 = 'opencvresult\\\\'+fnum[13:-4]+'.jpg'\n",
    "        cv2.imwrite(path1, resized)\n",
    "\n",
    "    # cv2.imshow(fnum,resized)\n",
    "    # cv2.waitKey(0)\n",
    "    # cv2.destroyAllWindows()\n",
    "    #按多次 O 键退出\n",
    "    if keyboard.is_pressed('o'):\n",
    "        break"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "6c385eb9-2277-4f73-8de7-45968e2ba87b",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'1 (29)'"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "fnum[13:-4]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "97b3bd4a-8845-4093-a657-cf2c7d1d91f4",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.11"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
